//
//  WBBaseRequest.m
//  WeatherBar
//
//  Created by Bert on 2024/6/7.
//

#import "WBBaseRequest.h"
#import <AFNetworking/AFNetworking.h>
#import "BaseNetRequest.h"


@interface WBBaseRequest ()
@property (nonatomic ,strong) BaseNetRequest *baseRequest;
@end

@implementation WBBaseRequest

#pragma mark - 类方法请求
/**
 包含BaseUrl的请求
 
 @param methodName 方法名字
 @param parametersDic 参数
 @param success 成功回调
 */
+(void)postRequestWithMethodName:(NSString *)methodName
                   parametersDic:(NSDictionary *)parametersDic
                         success:(successBlock)success
{
    WBBaseRequest *request = [self initRequestWithMethodName:methodName parametersDic:parametersDic];
    
    [request postRequestSuccess:^(WBBaseRequest *operation, id responseObject) {
        BOOL suc = (operation.requestStatus == RequestStatusSuccess);
        success(operation,suc,responseObject);
    } failure:^(WBBaseRequest *operation, NSError *error) {
        success(operation,NO,operation.resultMessage);
    }];
}
/**
 get包含Baseurl的请求
 
 @param methodName 方法名字
 @param parametersDic 参数
 @param success 成功回调
 */
+(void)getRequestWithMethodName:(NSString *)methodName
                  parametersDic:(NSDictionary *)parametersDic
                        success:(successBlock)success
{
    WBBaseRequest *request = [self initRequestWithMethodName:methodName parametersDic:parametersDic];
    
    [request getRequestSuccess:^(WBBaseRequest *operation, id responseObject) {
        BOOL suc = (operation.requestStatus == RequestStatusSuccess);
        success(operation,suc,responseObject);
    } failure:^(WBBaseRequest *operation, NSError *error) {
        success(operation,NO,operation.resultMessage);
    }];
}

/**
 put包含Baseurl的请求
 
 @param methodName 方法名字
 @param parametersDic 参数
 @param success 成功回调
 */
+(void)putRequestWithMethodName:(NSString *)methodName
                  parametersDic:(NSDictionary *)parametersDic
                        success:(successBlock)success
{
    WBBaseRequest *request = [self initRequestWithMethodName:methodName parametersDic:parametersDic];
    
    [request putRequestSuccess:^(WBBaseRequest *operation, id responseObject) {
        BOOL suc = (operation.requestStatus == RequestStatusSuccess);
        success(operation,suc,responseObject);
    } failure:^(WBBaseRequest *operation, NSError *error) {
        success(operation,NO,operation.resultMessage);
    }];
}

/**
 delete包含Baseurl的请求
 
 @param methodName 方法名字
 @param parametersDic 参数
 @param success 成功回调
 */
+(void)deleteRequestWithMethodName:(NSString *)methodName
                     parametersDic:(NSDictionary *)parametersDic
                           success:(successBlock)success {
    WBBaseRequest *request = [self initRequestWithMethodName:methodName parametersDic:parametersDic];
    
    [request deleteRequestSuccess:^(WBBaseRequest *operation, id responseObject) {
        BOOL suc = (operation.requestStatus == RequestStatusSuccess);
        success(operation,suc,responseObject);
    } failure:^(WBBaseRequest *operation, NSError *error) {
        success(operation,NO,operation.resultMessage);
    }];
}

/**
 上传头像的请求
 
 @param methodName 方法名字
 @param data 二进制
 @param success 成功回调
 */
+(void)postImageWithMethodName:(NSString *)methodName
                                 data:(NSData *)data
                              success:(successBlock)success
{
    WBBaseRequest *request = [self initRequestWithMethodName:methodName parametersDic:nil];
    request.data = data;
    [request uploadImgRequestSuccess:^(WBBaseRequest *operation, id responseObject) {
        BOOL suc = (operation.requestStatus == RequestStatusSuccess);
        success(operation,suc,responseObject);
    } failure:^(WBBaseRequest *operation, NSError *error) {
        success(operation,NO,operation.resultMessage);
    }];
}
/**
 上传多张头像的请求
 
 @param methodName 方法名字
 @param images 二进制数组
 @param success 成功回调
 */
+(void)postImagesArrayWithMethodName:(NSString *)methodName
                                      data:(NSArray <NSData *>*)images
                                   success:(successBlock)success
{
    WBBaseRequest *request = [self initRequestWithMethodName:methodName parametersDic:nil];
    request.imageArray = images;
    [request uploadImgArrRequestSuccess:^(WBBaseRequest *operation, id responseObject) {
        BOOL suc = (operation.requestStatus == RequestStatusSuccess);
        success(operation,suc,responseObject);
    } failure:^(WBBaseRequest *operation, NSError *error) {
        success(operation,NO,operation.resultMessage);
    }];
}
- (void)uploadImgRequestSuccess:(void (^)(WBBaseRequest *operation, id responseObject))success
                   failure:(void (^)(WBBaseRequest *operation, NSError *error))failure
{
    [self.baseRequest upLoadWithPOST:_methodName parameters:self.bodyDic image:self.data progress:^(NSProgress * _Nullable progress) {
        NSLog(@"---上传进度：%lld",progress.completedUnitCount/progress.totalUnitCount);
    } success:^(id  _Nonnull responseObject) {
        [self hanleSuccessResponse:responseObject success:success failure:failure];
    } failure:^(NSError * _Nonnull error) {
        [self handlerFailed:failure error:error];
    }];
}
- (void)uploadImgArrRequestSuccess:(void (^)(WBBaseRequest *operation, id responseObject))success
                   failure:(void (^)(WBBaseRequest *operation, NSError *error))failure
{
    [self.baseRequest upLoadWithPOST:_methodName parameters:self.bodyDic imageArray:self.imageArray progress:^(NSProgress * _Nullable progress) {
        NSLog(@"---上传进度：%lld",progress.completedUnitCount/progress.totalUnitCount);
    } success:^(id  _Nonnull responseObject) {
        [self hanleSuccessResponse:responseObject success:success failure:failure];
    } failure:^(NSError * _Nonnull error) {
        [self handlerFailed:failure error:error];
    }];
}


/**
 baseRequest初始化

 @param methodName 方法名
 @param parametersDic 参数
 @return 实例对象
 */
+(WBBaseRequest*)initRequestWithMethodName:(NSString *)methodName
                               parametersDic:(NSDictionary *)parametersDic
{
    WBBaseRequest *request = [[WBBaseRequest alloc] init];
    request.methodName = methodName;
    [request.bodyDic addEntriesFromDictionary:parametersDic];
    return request;
}



//--------------------------------对象方法--------------------------------------
#pragma mark - 对象方法

- (id)init
{
    self = [super init];
    if (self){
        self.headerDic = [NSMutableDictionary dictionary];
        self.bodyDic = [NSMutableDictionary dictionary];
        self.baseRequest = [BaseNetRequest sharedInstance];
        self.baseRequest.BaseUrl = [WBEnvironmentManager shareManager].environmentUrl;
        [self setDefaultParameter];
        [self signHeader];
    }
    return self;
}

/**
 设置默认的请求参数，包含header和body
 */
- (void)setDefaultParameter
{
    //设置header
    NSString *token;
//    NSDictionary *dic = [JYDBManager getInDocumentWithObjectByFileName:NSStringFromClass([WBUserModel class])];
//    WBUserModel *userModel = [WBUserModel modelWithDictionary:dic];
//    if (userModel.token.length) {
//        token = userModel.token;
//    }else{
//        token = @"";
//    }
    [self.headerDic setValue:@"" forKey:@"token"];

    //[self setValue]设置的是body
}

/// 对 header加密，并设置到httpSessionManager.requestSerializer中
- (void)signHeader
{
    //将基本信息进行加密
    [self.baseRequest updateSessionManagerHeaderFields:self.headerDic timeoutInterval:30];
    /*
    /// 加签规则：md5(token&md5(data)&s&key) md5 的时候，加盐处理
    NSDictionary *bundleInfoDic = [[NSBundle mainBundle] infoDictionary];
     NSString *version = [bundleInfoDic valueForKey:@"CFBundleVersion"];

     NSString *token;
     if ([THUserInfoManager shareManager].token.length) {
         token = [THUserInfoManager shareManager].token;
     }else{
         token = [THUserInfoManager getTempToken];
     }
     
     NSString *key = @"EC281B86547249B704";
     NSString *s = @"APP";
     /// 字典转字符串，options 为 0 ，代表没有换行，否则有换行
     
     NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self.parametersDic
                                                        options:0
                                                          error:nil];
     
     NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
     
     /// md5 的 盐
     NSString *t = [self randomSalt];
     NSString *md5DataStr = [THHelper md5String:[NSString stringWithFormat:@"%@&%@",jsonString,t]];
     NSString *finalStr = [NSString stringWithFormat:@"%@&%@&%@&%@",token,md5DataStr,s,key];
     NSString *sign = [THHelper md5String:[NSString stringWithFormat:@"%@&%@",finalStr,t]];
     NSString * memberId = [NSString stringWithFormat:@"%ld",(long)[THUserInfoManager shareManager].memberId];
     NSDictionary *dict = @{
         @"sign":sign,
         @"s":s,
         @"token":token,
         @"t":t,
         @"memberId":memberId,
         @"version":version
     };
     [self.baseRequest updateSessionManagerHeaderFields:dict timeoutInterval:30];
     */
    
}

#pragma mark 各种设置 value 的方法
- (void)  setIntegerValue:(NSInteger)value forKey:(NSString *)key
{
    [self setValue:[NSString stringWithFormat:@"%ld", (long)value] forKey:key];
}
- (void)setDoubleValue:(double)value forKey:(NSString *)key
{
    [self setValue:[NSString stringWithFormat:@"%f", value] forKey:key];
}
- (void)setLongLongValue:(long long)value forKey:(NSString *)key
{
    [self setValue:[NSString stringWithFormat:@"%lld", value] forKey:key];
}
- (void)setBOOLValue:(BOOL)value forKey:(NSString *)key
{
    [self setValue:[NSString stringWithFormat:@"%d", value] forKey:key];
}
- (void)setValue:(id)value forKey:(NSString *)key
{
    if(!value){
        // value = @"";
        return;
    }
    [self.bodyDic setValue:value forKey:key];
}
#pragma mark PrivateMethod
// 网络是否联通状态
- (BOOL)checkNetReachability
{
    AFNetworkReachabilityStatus status = [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;
    if  (status!= AFNetworkReachabilityStatusNotReachable) {
        return YES;
    }
    else {
        return NO;
    }
}

#pragma mark 真实请求
- (void)getRequestSuccess:(void (^)(WBBaseRequest *operation, id responseObject))success
                  failure:(void (^)(WBBaseRequest *operation, NSError *error))failure
{
    [self startRequestWithType:RequestTypeGet success:success failure:failure];
}

- (void)postRequestSuccess:(void (^)(WBBaseRequest *operation, id responseObject))success
                   failure:(void (^)(WBBaseRequest *operation, NSError *error))failure
{
    [self startRequestWithType:RequestTypePost success:success failure:failure];
}
- (void)putRequestSuccess:(void (^)(WBBaseRequest *operation, id responseObject))success
                   failure:(void (^)(WBBaseRequest *operation, NSError *error))failure
{
    [self startRequestWithType:RequestTypePut success:success failure:failure];
}
- (void)deleteRequestSuccess:(void (^)(WBBaseRequest *operation, id responseObject))success
                   failure:(void (^)(WBBaseRequest *operation, NSError *error))failure
{
    [self startRequestWithType:RequestTypeDelete success:success failure:failure];
}

#pragma mark - 到BaseNetRequest请求
- (void)startRequestWithType:(RequestType)type
                     success:(void (^)(WBBaseRequest *operation, id responseObject))success
                     failure:(void (^)(WBBaseRequest *operation, NSError *error))failure
{
    ///  检查网络状况
    if ([self checkNetReachability]) {
//        [self signHeader];
        //去BaseNetRequest请求
        [self.baseRequest requestWithType:(type?type:RequestTypePost) url:_methodName parameters:_bodyDic success:^(id  _Nonnull responseObject) {
            [self hanleSuccessResponse:responseObject success:success failure:failure];
        } failure:^(NSError * _Nonnull error) {
            [self handlerFailed:failure error:error];
        }];
    }
    else{
        [self handlerFailed:failure error:nil];
    }
}


#pragma mark 处理返回结果
- (void)hanleSuccessResponse:(id)responseObject
                                  success:(void (^)(WBBaseRequest *operation, id responseObject))success
                                  failure:(void (^)(WBBaseRequest *operation, NSError *error))failure {

    NSMutableDictionary* resultDic = nil;
    if ([responseObject isKindOfClass:[NSDictionary class]]) {
        resultDic = responseObject;
    }
    else {
        NSData* clearData = responseObject;
        if (clearData) {
            resultDic = (NSMutableDictionary *)clearData;//[LSHelper parserJsonData:clearData];
            if(![resultDic isKindOfClass:[NSDictionary class]]) {
                resultDic = nil;
            }
        }
    }
    
    if (resultDic && resultDic[@"message"]) {
        self.resultMessage = [NSString stringWithFormat:@"%@",resultDic[@"message"]];
    }
    
#warning mark 这个参数：resultDic[@"code"]需要根据不同团队进行调整。
    if (resultDic && [resultDic[@"status"] isKindOfClass:[NSNumber class]] && [(NSNumber *)resultDic[@"status"] intValue]==0) {
        self.isError = NO;
        self.code = resultDic[@"status"];
    }
    else {
        self.isError = YES;
        self.code = resultDic[@"status"];
    }
        
    if (!self.isError) {
        self.requestStatus = RequestStatusSuccess;
        success(self, resultDic);
    } else {
        self.requestStatus = RequestStatusFormatError;
        failure(self, nil);
    }
}
- (void)handlerFailed:(void (^)(WBBaseRequest *operation, NSError *error))failure error:(NSError *)error
{
    AFNetworkReachabilityStatus status = [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;
    if  (status!= AFNetworkReachabilityStatusNotReachable && status!= AFNetworkReachabilityStatusUnknown) {
        self.requestStatus = RequestStatusRemoteFaild;
        if ([error.userInfo valueForKey:@"NSLocalizedDescription"]) {
            NSString *errorMsg = error.userInfo[@"NSLocalizedDescription"];
            if (errorMsg.length) {
                //替换为网络提示
                self.resultMessage = @"网络超时，请稍后再访问!";
            } else {
                self.resultMessage = @"网络超时，请稍后再访问!";
            }
        } else {
            self.resultMessage = @"网络超时，请稍后再访问!";
        }
    }
    else{
        self.requestStatus = RequestStatusCanNotReachable;
        self.resultMessage = @"您的网络不给力！";
    }
    
    failure(self, nil);
}

@end
